package structs

import (
	"strings"
	"time"

	"github.com/buger/jsonparser"
	"github.com/pkg/errors"
)

type Song struct {
	Id int64 `json:"id"`
	Name string `json:"name"`
	Duration time.Duration `json:"duration"`
	Artists []Artist `json:"artists"`
	Album `json:"album"`
}

func (s Song) ArtistName() string {
	var artistNames []string
	for _, artist := range s.Artists {
		artistNames = append(artistNames, artist.Name)
	}

	return strings.Join(artistNames, ",")
}

// NewSongFromShortNameSongsJson Get data from SongList
func NewSongFromShortNameSongsJson(json []byte) (Song, error) {
	var song Song
	if len(json) == 0 {
		return song, errors.New("json is empty")
	}

	id, err := jsonparser.GetInt(json, "id")
	if err != nil {
		return song, err
	}

	song.Id = id

	if name, err := jsonparser.GetString(json, "name"); err == nil {
		song.Name = name
	}

	if duration, err := jsonparser.GetInt(json, "dt"); err == nil {
		song.Duration = time.Millisecond * time.Duration(duration)
	}

	album, err := NewAlbumFromJson(json)
	if err == nil {
		song.Album = album
	}

	_, _ = jsonparser.ArrayEach(json, func(value []byte, dataType jsonparser.ValueType, offset int, _ error) {
		artist, err := NewArtist(value)
		if err == nil {
			song.Artists = append(song.Artists, artist)
		}
	}, "ar")

	return song, nil
}


// NewSongFromfmJson Get data from private fm
func NewSongFromfmJson(json []byte) (Song, error) {
	var song Song
	if len(json) == 0 {
		return song, errors.New("json is empty")
	}

	id, err := jsonparser.GetInt(json, "id")
	if err != nil {
		return song, err
	}

	song.Id = id

	if name, err := jsonparser.GetString(json, "name"); err == nil {
		song.Name = name
	}

	if duration, err := jsonparser.GetInt(json, "duration"); err == nil {
		song.Duration = time.Millisecond * time.Duration(duration)
	}

	if alId, err := jsonparser.GetInt(json , "album", "id"); err == nil {
		song.Album.Id = alId
	}

	if alName, err := jsonparser.GetString(json, "album", "name"); err == nil {
		song.Album.Name = alName
	}

	if alPic, err := jsonparser.GetString(json, "album", "picUrl"); err == nil {
		song.Album.PicUrl = alPic
	}

	_, _ = jsonparser.ArrayEach(json, func(value []byte, dataType jsonparser.ValueType, offset int, _ error){
		artist, err := NewArtist(value)
		if err == nil {
			song.Artists = append(song.Artists, artist)
		}
	}, "artists")

	return song, nil
}

// NewSongFromIntelligenceJson Get data from heartbeat mode
func NewSongFromIntelligenceJson(json []byte)(Song, error) {
	var song Song
	if len(json) == 0 {
		return song, errors.New("json is empty")
	}

	id, err := jsonparser.GetInt(json, "songInfo", "id")
	if err != nil {
		return song, err
	}

	song.Id = id

	if name, err := jsonparser.GetString(json, "songInfo", "name"); err == nil {
		song.Name = name
	}

	if duration, err := jsonparser.GetInt(json, "songInfo", "dt"); err == nil {
		song.Duration = time.Millisecond * time.Duration(duration)
	}

	if alId, err := jsonparser.GetInt(json, "songInfo", "al", "name"); err == nil {
		song.Album.Name = alName
	}

	if alPic, err := jsonparser.GetString(json, "songInfo", "al", "picUrl"); err == nil {
		song.Album.PicUrl = alPic
	}
	
	_, _ = jsonparser.ArrayEach(json, func(value []byte, dataType jsonparser.ValueType, offset int, _ error){
		artist, err := NewArtist(value)

		if err == nil {
			song.Artists = append(song.Artists, artist)
		}
	}, "songInfo", "ar")

	return song, nil
}

// TODO: line 142
